package com.wyg.lambda.methodref.constructorref;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 *
 * 四、构造方法引用
 *
 * 如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现，那么就可以使用构造方法引用。
 *
 * 方法引用-表达式：
 *          类名::new   【仅仅表示引用，所以不需要new方法名后面加()】
 *
 * 对应普通Lambda-表达式：
 *          (args) -> new 类名(args)
 *
 *
 * @ClassName: ConstructorRef
 * @Auther: WangYG
 * @Date: 2020-02-22 01:07:33
 * @Version: 1.0
 */
public class ConstructorRef {

    /**
     * 功能描述: 演示简单的Lambda表示式-构造方法引用示例-无参构造方法调用的演示
     * @methodName: one
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-22 01:19:17
     */
    public void one(){

        //1.普通Lambda表达式-调用构造函数
        Supplier<Dog> s1 = () -> new Dog();
        //2.Lambda表达式-构造方法引用-实例
        Supplier<Dog> s2 = Dog::new;
        s1.get();
        s2.get();

        //根据上面测试，同理可以得出无参构造函数都可以这样new
        Supplier<List> list = ArrayList::new;
        Supplier<Set> set = HashSet::new;
        Supplier<Map> map = HashMap::new;
        Supplier<String> str = String::new;
        Supplier<Thread> thread = Thread::new;
    }

    /**
     * 功能描述: 演示简单的Lambda表示式-构造方法引用示例-有一个参数的构造方法调用的演示
     * @methodName: two
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-22 01:34:27
     */
    public void two(){
        //1.普通Lambda表达式-调用构造函数
        Consumer<Integer> c1 = (Integer age) -> new Dog(age);
        //2.Lambda表达式-构造方法引用-实例
        Consumer<Integer> c2 = Dog::new;
        c1.accept(18);
        c1.accept(19);

        //1.普通Lambda表达式-调用构造函数
        Consumer<String> c3 = name -> new Dog(name);
        //2.Lambda表达式-构造方法引用-实例
        Consumer<String> c4 = Dog::new;
        c3.accept("小狗1");
        c4.accept("小狗2");
    }

    /**
     * 功能描述: 演示简单的Lambda表示式-构造方法引用示例-有多个参数的构造方法调用 并返回对象 的演示
     * @methodName: three
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-22 01:43:00
     */
    public void three(){

        //1.普通Lambda表达式-调用构造函数
        Function<Integer,Dog> f1 = (Integer age) -> {return new Dog(age);};
        //2.Lambda表达式-构造方法引用-实例
        Function<Integer,Dog> f2 =  Dog::new;
        Dog dog1 = f1.apply(15);
        Dog dog2 = f2.apply(16);

        //1.普通Lambda表达式-调用构造函数
        Function<String, Dog> f3 = name -> new Dog(name);
        //2.Lambda表达式-构造方法引用-实例
        Function<String, Dog> f4 = Dog::new;
        Dog dog3 = f3.apply("小狗1");
        Dog dog4 = f4.apply("小狗2");

        //1.普通Lambda表达式-调用构造函数
        BiFunction<Integer, String,Dog> f5 = (Integer age, String name) -> {return new Dog(age, name);};
        //2.Lambda表达式-构造方法引用-实例
        BiFunction<Integer, String,Dog> f6 = Dog::new;
        Dog dog5 = f5.apply(21,"大狗1");
        Dog dog6 = f6.apply(22,"大狗2");

        //1.普通Lambda表达式-调用构造函数
        BiFunction<Integer, String,Dog> f7 = (age,name) -> new Dog(age, name);
        //2.Lambda表达式-构造方法引用-实例
        BiFunction<Integer, String,Dog> f8 = Dog::new;
        Dog dog7 = f7.apply(31,"老狗1");
        Dog dog8 = f8.apply(32,"老狗2");
    }

}

class Dog{

    public Dog(){
        System.out.println("Dog No args Constructor() Method...");
    }

    public Dog(Integer age){
        System.out.println("Dog one Integer Parames Constructor(Integer age) Method... age is : " + age);
    }

    public Dog(String name){
        System.out.println("Dog one String Parames Constructor(String name) Method... name is : " + name);
    }

    public Dog(Integer age,String name){
        System.out.println("Dog two Parames Constructor(Integer age,String name) Method... (age,name) is : " + age +","+name);
    }

}
